/*#include <stdio.h>
#include <stdlib.h>
int main()
{
    int n, m, a, j,f[1001];
    scanf("%d%d", &n, &m);
    memset(f, 0, sizeof(f));
    while (n--)
    {
        scanf("%d", &a);
        for (j = a; j <= m; j++)
        {
            // 如果当前位置j等于a，则将f[j]加1；否则，将f[j]更新为f[j-a]的值
            // f[j] += j == a ? 1 : f[j - a];

            // f[j] += j == a ? 1 : f[j - a]; 相当于--> f[j] += (j == a ? 1 : f[j - a]);  相当于-->  f[j] = f[j] + (j == a ? 1 : f[j - a]);
            // 其中 (j == a ? 1 : f[j - a]);  // <-- 这是C语言的三目运算符逗号运行表达式，等价于下面这行代码

            // 三目运算符定义：(a ？b : c)  当a的值为真时，返回b的值；否则返回c的值
            int x;
            if (j == a)
            {
                x = 1;
            }
            else
            {
                x = f[j - a];
            }
            //printf("j=%d a=%d x=%d f[j]=%d\n",j,a,x,f[j]);
            f[j] += x;
            printf("j=%d a=%d x=%d f[j]=%d\n",j,a,x,f[j]);
        }
    }
    printf("%d", f[m]);
}
*/
#include <stdio.h>
#include <stdlib.h>
int sum=0,m,n;
int MianZ[1001];
//递归函数，x:当前子集的和，key当前处理的元素在数组中的位置
void YingB(int x,int key)
{
  int i;
  if(x==m)//首先判断当前自己的和是否等于m，如果是则将符合条件的子集个数sum加一返回
  {
    sum++;
    return;
  }
  else if(x>m) return;//如果大于m，直接返回
  for(i=key;i<n;i++)//否则从key开始遍历，每次递归调用YingB函数并传入新的和以及当前处理的元素位置。
  {
    YingB(x+MianZ[i],i);
  }
  //通过不断递归调用，可以得到所有和为m的子集个数
}
main()
{
  int i;
  scanf("%d%d",&n,&m);
  for(i=0;i<n;i++)
  {
    scanf("%d",MianZ+i);
  }
  for(i=0;i<n;i++)
  {
    YingB(MianZ[i],i);
  }
  printf("%d",sum);
}
